package com.timk.goserver.client.board;

import com.timk.goserver.client.compatibility.Point;

/**
 * Command base class
 * @author TKington
 *
 */
public abstract class AbstractCommand {
	protected final BoardController controller;
	protected Board board;
	protected int player;
	private final Point prevMoveLocation;
	private final Point prevKoPoint;
	protected String comment;
	
	/**
	 * Creates an AbstractCommand
	 * @param controller the BoardController
	 * @param board the Board
	 * @param player the player - 0 to find using previous move
	 * @param prevMove the previous Command
	 * @param comment the comment for the move
	 */
	public AbstractCommand(BoardController controller, Board board, int player,
			AbstractCommand prevMove, String comment) {
		this.controller = controller;
		this.board = board;
		this.player = player;
		this.comment = comment;
		
		if(prevMove == null) {
			if(this.player == 0) {
				this.player = 1;
			}
			prevKoPoint = null;
			prevMoveLocation = null;
		} else {
			if(this.player == 0) {
				this.player = prevMove.getPlayer() * -1;
			}
			prevKoPoint = prevMove.getKoPoint();
			prevMoveLocation = prevMove.getLocation();
		}
	}
	
	/** Executes the command */
	public void doIt() {
		//	Clear curMove marker
		if(prevMoveLocation != null &&
				prevMoveLocation.x != BoardController.PASS_COORD) {
			board.setMarkAt(prevMoveLocation, Board.MARK_NONE);
		}
		
		localDoIt();
	}
	
	/** Undoes the command */
	public void undoIt() {
		localUndoIt();

    	//	Set curMove marker and koPoint back to original values
    	board.setKoPoint(prevKoPoint);
    	if(prevMoveLocation != null &&
    			prevMoveLocation.x != BoardController.PASS_COORD) {
    		board.setMarkAt(prevMoveLocation, Board.MARK_CURMOVE);
    	}
	}

	
	/**
	 * Returns the player
	 * @return the player
	 */
	public int getPlayer() { return player; }
	
	/** Does the specific work of this command */
	public abstract void localDoIt();
	/** Undoes the specific work of this command */
	public abstract void localUndoIt();

	/**
	 * Returns the x,y location
	 * @return the x,y location
	 */
	public abstract Point getLocation();
	
	/**
	 * Returns the ko point
	 * @return the ko point
	 */
	public abstract Point getKoPoint();

	/**
	 * Converts this move to SGF format, and appends to the buffer
	 * @param buf the StringBuffer
	 */
	public abstract void toSgf(StringBuffer buf);

	/**
	 * Returns the node comment
	 * @return the node comment
	 */
	public String getComment() {
		return comment;
	}

	/**
	 * Sets the node comment
	 * @param comment
	 */
	public void setComment(String comment) {
		this.comment = comment;
	}
}
